﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell;

namespace VSIXUtilities.EventsListeners
{
    public delegate void ProjectSimpleEventHandler(IVsHierarchy EntityHierarchy);
	public class VsSolutionEvents : IVsSolutionEvents, IDisposable
	{
		#region Fields
		
		IVsSolution2 solution;
		private uint pdwCookie;

		#endregion

		#region Constructors

		public VsSolutionEvents()
		{
			solution = ServiceProvider.GlobalProvider.GetService(typeof(SVsSolution)) as IVsSolution2;
			if(solution != null)
			{
				solution.AdviseSolutionEvents(this, out pdwCookie);
			}
		}
		#endregion

		public event EventHandler AfterOpenSolution;
        public event EventHandler BeforeCloseSolution;
        public event EventHandler AfterCloseSolution;
        public event ProjectSimpleEventHandler AfterOpenProject;
        public event ProjectSimpleEventHandler AfterLoadProject;
        public event ProjectSimpleEventHandler BeforeUnloadProject;
        public event ProjectSimpleEventHandler BeforeCloseProject;
		
		#region IVsSolutionEvents Members

        public int OnQueryCloseSolution(object pUnkReserved, ref int pfCancel)
        {
            return VSConstants.S_OK;
        }

        public int OnBeforeCloseSolution(object pUnkReserved)
        {
            if (BeforeCloseSolution != null)
            {
                BeforeCloseSolution(this, EventArgs.Empty);
            }
            return VSConstants.S_OK;
        }

		public int OnAfterCloseSolution(object pUnkReserved)
		{
			if(AfterCloseSolution != null)
			{
				AfterCloseSolution(this, EventArgs.Empty);
			}
			return VSConstants.S_OK;
		}

        public int OnAfterOpenSolution(object pUnkReserved, int fNewSolution)
        {
            if (AfterOpenSolution != null)
            {
                AfterOpenSolution(this, EventArgs.Empty);
            }
            return VSConstants.S_OK;
        }

        public int OnQueryUnloadProject(IVsHierarchy pRealHierarchy, ref int pfCancel)
        {
            return VSConstants.S_OK;
        }

		public int OnAfterLoadProject(IVsHierarchy pStubHierarchy, IVsHierarchy pRealHierarchy)
		{
            if (AfterLoadProject != null)
            {
                AfterLoadProject(pRealHierarchy);
            }
            return VSConstants.S_OK;
		}

		public int OnAfterOpenProject(IVsHierarchy pHierarchy, int fAdded)
		{
            if (AfterOpenProject != null)
            {
                AfterOpenProject(pHierarchy);
            }
            return VSConstants.S_OK;
		}

		public int OnBeforeCloseProject(IVsHierarchy pHierarchy, int fRemoved)
		{
            if (BeforeCloseProject != null)
            {
                BeforeCloseProject(pHierarchy);
            }
            return VSConstants.S_OK;
		}

		public int OnBeforeUnloadProject(IVsHierarchy pRealHierarchy, IVsHierarchy pStubHierarchy)
		{
            if (BeforeUnloadProject != null)
            {
                BeforeUnloadProject(pRealHierarchy);
            }
            return VSConstants.S_OK;
		}

		public int OnQueryCloseProject(IVsHierarchy pHierarchy, int fRemoving, ref int pfCancel)
		{
			return VSConstants.S_OK;
		}

		#endregion

		#region IDisposable Members

		public void Dispose()
		{
			if(solution != null && pdwCookie != 0)
			{
				solution.UnadviseSolutionEvents(pdwCookie);
			}
		}

		#endregion
	}
}
